package com.ecoolex.ying.space.core.manager;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.modularize.api.ModuleConstant;
import com.ecoolex.framework.modularize.api.service.audit.AuditFieldType;
import com.ecoolex.framework.modularize.api.service.audit.AuditService;
import com.ecoolex.framework.modularize.api.service.audit.apply.ApplyEntity;
import com.ecoolex.framework.modularize.api.service.audit.apply.ApplyStorage;
import com.ecoolex.framework.modularize.api.service.audit.apply.ApplyText;
import com.ecoolex.framework.modularize.api.service.audit.apply.AuditApply;
import com.ecoolex.framework.modularize.api.service.audit.register.AuditEntityRegister;
import com.ecoolex.framework.modularize.api.service.audit.register.AuditFieldRegister;
import com.ecoolex.framework.modularize.api.service.audit.register.AuditRegister;
import com.ecoolex.framework.modularize.api.service.audit.result.AuditResult;
import com.ecoolex.framework.modularize.api.service.audit.result.AuditStatus;
import com.ecoolex.framework.modularize.api.service.audit.result.EntityResult;
import com.ecoolex.framework.modularize.api.service.audit.result.FieldResult;
import com.ecoolex.ying.space.core.CoreConstant;
import com.ecoolex.ying.space.entity.UserWorks;
import com.ecoolex.ying.space.entity.UserWorksComment;
import com.ecoolex.ying.space.entity.UserWorksImages;
import com.ecoolex.ying.space.entity.UserWorksOpus;
import com.ecoolex.ying.space.entity.UserWorksOpusItems;
import com.ecoolex.ying.space.entity.UserWorksShopping;
import com.ecoolex.ying.space.entity.UserWorksVideo;
import com.ecoolex.ying.space.enums.UserWorksAuditStatus;
import com.ecoolex.ying.space.enums.UserWorksCommentAuditStatus;


/**
 * 用户作品审核
 * 
 * @author shaon
 */
@Component
public class UserWorksAuditManager {

    private Logger log = LoggerFactory.getLogger(UserWorksAuditManager.class);

    @Autowired
    private AuditService service;

    private AuditFieldRegister coverImageField = new AuditFieldRegister("coverImage", "封面图", AuditFieldType.TEXT, true);

    private AuditFieldRegister titleField = new AuditFieldRegister("title", "标题", AuditFieldType.TEXT, true);

    // 购物
    private AuditFieldRegister linkNameField = new AuditFieldRegister("linkName", "链接名称", AuditFieldType.TEXT, true);

    private AuditFieldRegister labelField = new AuditFieldRegister("label", "标签", AuditFieldType.TEXT, true);

    private AuditEntityRegister shoppingEntity
        = new AuditEntityRegister("UserWorksShopping", "作品购物信息", labelField, linkNameField);

    // 图片
    private AuditFieldRegister imageField = new AuditFieldRegister("image", "图片", AuditFieldType.STORAGE, true);

    private AuditFieldRegister imageContentField = new AuditFieldRegister("content", "内容", AuditFieldType.TEXT, true);

    private AuditEntityRegister imagesEntity
        = new AuditEntityRegister("UserWorksImages", "图片作品", titleField, imageField, imageContentField);

    // 视频
    private AuditFieldRegister videoField = new AuditFieldRegister("video", "视频", AuditFieldType.STORAGE, true);

    private AuditFieldRegister videoContentField = new AuditFieldRegister("content", "内容", AuditFieldType.TEXT, true);

    private AuditEntityRegister videoEntity
        = new AuditEntityRegister("UserWorksVideo", "视频作品", titleField, videoField, videoContentField);

    // 作品
    private AuditFieldRegister statementDescriptionField
        = new AuditFieldRegister("statementDescription", "申明描述", AuditFieldType.TEXT, true);

    private AuditFieldRegister areaDescriptionField
        = new AuditFieldRegister("areaDescription", "面积描述", AuditFieldType.TEXT, true);

    private AuditFieldRegister styleDescriptionField
        = new AuditFieldRegister("styleDescription", "风格描述", AuditFieldType.TEXT, true);

    private AuditFieldRegister vrLinkField = new AuditFieldRegister("vrLink", "VR链接", AuditFieldType.TEXT, true);

    private AuditEntityRegister opusEntity
        = new AuditEntityRegister("UserWorksOpus", "作品", coverImageField, titleField, statementDescriptionField, areaDescriptionField, styleDescriptionField, vrLinkField);

    // 作品条目
    private AuditFieldRegister itmeNameField = new AuditFieldRegister("name", "名称", AuditFieldType.TEXT, true);

    private AuditFieldRegister itmeImageField = new AuditFieldRegister("video", "图片", AuditFieldType.STORAGE, true);

    private AuditFieldRegister itmeDescriptionField
        = new AuditFieldRegister("description", "描述", AuditFieldType.TEXT, true);

    private AuditEntityRegister opusItmeEntity
        = new AuditEntityRegister("UserWorksOpusItme", "作品条目", itmeNameField, itmeImageField, itmeDescriptionField);

    // 作品审核注册
    private AuditRegister worksRegister
        = new AuditRegister("UserWorks", "用户作品", CoreConstant.MODULE_NAME, imagesEntity, videoEntity, opusEntity, opusItmeEntity, shoppingEntity);

    // 评论
    private AuditFieldRegister commentContentField = new AuditFieldRegister("content", "内容", AuditFieldType.TEXT, true);

    private AuditFieldRegister commentImageField = new AuditFieldRegister("image", "图片", AuditFieldType.STORAGE, true);

    private AuditEntityRegister commentEntity
        = new AuditEntityRegister("UserWorksComment", "评论", commentContentField, commentImageField);

    // 评论注册
    private AuditRegister commentRegister
        = new AuditRegister("UserWorksComment", "用户作品评论", CoreConstant.MODULE_NAME, commentEntity);

    @Autowired
    public void register() {
        service.register(worksRegister);
        service.register(commentRegister);
    }

    @Autowired
    private UserWorksManager userWorksManager;

    /**
     * 申请图片审核
     * 
     * @param userWorks
     * @param userWorksImages
     * @param shoppingList
     */
    public void applyImages(UserWorks userWorks, UserWorksImages userWorksImages, List<UserWorksShopping> shoppingList) {
        AuditApply apply = new AuditApply(worksRegister, String.valueOf(userWorks.getWorksId()), userWorks.getUserId());

        // 标题和内容
        ApplyEntity images = new ApplyEntity(imagesEntity, String.valueOf(userWorksImages.getWorksId()));
        images.addContent(new ApplyText(titleField, userWorks.getTitle()));
        images.addContent(new ApplyText(imageContentField, userWorksImages.getContent()));
        // 图片
        JSON.parseArray(userWorksImages.getImages(), String.class).forEach(image -> {
            images.addContent(new ApplyStorage(imageField, image));
        });
        apply.addEntity(images);
        // 标签
        shoppingApply(apply, shoppingList);

        // 异步申请
        int recordId = service.applyAsync(apply);
        // 设置记录Id
        userWorksManager.settingAuditRecordId(userWorks, recordId, this.getClass().getSimpleName());
    }

    /**
     * 申请视频审核
     * 
     * @param userWorks
     * @param userWorksVideo
     * @param shoppingList
     */
    public void applyVideo(UserWorks userWorks, UserWorksVideo userWorksVideo, List<UserWorksShopping> shoppingList) {
        AuditApply apply = new AuditApply(worksRegister, String.valueOf(userWorks.getWorksId()), userWorks.getUserId());
        // 视频
        ApplyEntity video = new ApplyEntity(videoEntity, String.valueOf(userWorksVideo.getWorksId()));
        video.addContent(new ApplyText(titleField, userWorks.getTitle()));
        video.addContent(new ApplyText(videoContentField, userWorksVideo.getContent()));
        video.addContent(new ApplyStorage(videoField, userWorksVideo.getVideo()));
        apply.addEntity(video);

        // 标签
        shoppingApply(apply, shoppingList);
        // 异步申请
        int recordId = service.applyAsync(apply);
        // 设置记录Id
        userWorksManager.settingAuditRecordId(userWorks, recordId, this.getClass().getSimpleName());
    }

    /**
     * 申请作品审核
     * 
     * @param userWorks
     * @param userWorksOpus
     * @param opusItemList
     * @param shoppingList
     */
    public void applyOpus(UserWorks userWorks, UserWorksOpus userWorksOpus, List<UserWorksOpusItems> opusItemList, List<UserWorksShopping> shoppingList) {
        AuditApply apply = new AuditApply(worksRegister, String.valueOf(userWorks.getWorksId()), userWorks.getUserId());

        // 标题, 封面图
        ApplyEntity opus = new ApplyEntity(opusEntity, String.valueOf(userWorks.getWorksId()));
        opus.addContent(new ApplyStorage(coverImageField, userWorks.getCoverImage()));
        opus.addContent(new ApplyText(titleField, userWorks.getTitle()));
        // 声明, 面积, 风格, Vr链接
        if (Check.notNullOrTrimEmpty(userWorksOpus.getStatementDescription())) {
            opus.addContent(new ApplyText(statementDescriptionField, userWorksOpus.getStatementDescription()));
        }
        if (Check.notNullOrTrimEmpty(userWorksOpus.getAreaDescription())) {
            opus.addContent(new ApplyText(areaDescriptionField, userWorksOpus.getAreaDescription()));
        }
        if (Check.notNullOrTrimEmpty(userWorksOpus.getStyleDescription())) {
            opus.addContent(new ApplyText(styleDescriptionField, userWorksOpus.getStyleDescription()));
        }
        if (Check.notNullOrTrimEmpty(userWorksOpus.getVrLink())) {
            opus.addContent(new ApplyText(vrLinkField, userWorksOpus.getVrLink()));
        }

        // 条目名称, 图片集合, 条目描述
        opusItemList.forEach(opusItem -> {
            ApplyEntity item = new ApplyEntity(opusItmeEntity, String.valueOf(opusItem.getItemId()));

            item.addContent(new ApplyText(itmeNameField, opusItem.getName()));
            // 图片
            JSON.parseArray(opusItem.getImages(), String.class).forEach(image -> {
                item.addContent(new ApplyStorage(itmeImageField, userWorks.getCoverImage()));
            });
            if (Check.notNullOrTrimEmpty(opusItem.getDescription())) {
                item.addContent(new ApplyText(itmeDescriptionField, opusItem.getDescription()));
            }
            apply.addEntity(item);
        });

        // 标签
        shoppingApply(apply, shoppingList);
        // 异步申请
        int recordId = service.applyAsync(apply);
        // 设置记录Id
        userWorksManager.settingAuditRecordId(userWorks, recordId, this.getClass().getSimpleName());
    }

    private AuditApply shoppingApply(AuditApply apply, List<UserWorksShopping> shoppingList) {
        // 标签内容
        shoppingList.forEach(shopping -> {
            ApplyEntity shoppingEntity = new ApplyEntity(this.shoppingEntity, String.valueOf(shopping.getId()));
            if (Check.notNullOrEmpty(shopping.getLabel())) {
                shoppingEntity.addContent(new ApplyText(labelField, shopping.getLabel()));
            }
            if (Check.notNullOrEmpty(shopping.getLinkName())) {
                shoppingEntity.addContent(new ApplyText(linkNameField, shopping.getLinkName()));
            }
            if (!shoppingEntity.getContentList().isEmpty()) {
                apply.addEntity(shoppingEntity);
            }
        });
        return apply;
    }

    private void resetAuditStatus(UserWorks userWorks, AuditResult result) {
        boolean updateSuccessful = false;
        if (result.getStatus() == AuditStatus.PASS) {
            // 审核通过
            updateSuccessful = userWorksManager.resetAuditStatus(userWorks,
                UserWorksAuditStatus.PASS,
                this.getClass().getSimpleName());
        } else if (result.getStatus() == AuditStatus.REJECT) {
            // 审核拒绝
            updateSuccessful = userWorksManager.resetAuditStatus(userWorks,
                UserWorksAuditStatus.REFUSE,
                this.getClass().getSimpleName());
        } else {
            // 审核中, 不处理并退出
            userWorksManager.resetAuditStatus(userWorks,
                UserWorksAuditStatus.WAITAUDIT,
                this.getClass().getSimpleName());
            log.debug("作品Id={}, 审核Id={}, 审核中状态, 退出.", userWorks.getWorksId(), userWorks.getAuditRecordId());
            return;
        }

        if (!updateSuccessful) {
            log.debug("作品Id={}, 审核Id={}, 修改审核状态失败, 可能作品已经被修改.", userWorks.getWorksId(), userWorks.getAuditRecordId());
            return;
        }
        // 内容修改 TODO
        if (result.getContentUpdate()) {

        }
    }

    /**
     * 作品审核结果通知
     * 
     * @param result
     */
    public void worksAuditNotify(AuditResult result) {
        Integer worksId = Integer.valueOf(result.getRootDataId());
        UserWorks userWorks = userWorksManager.getByWorksIdAndAuditRecordId(worksId, result.getRecordId());
        if (Check.notNull(userWorks)) {
            resetAuditStatus(userWorks, result);
        } else {
            log.debug("审核记录Id={}未找到与之对应的作品Id={}", result.getRecordId(), worksId);
        }
    }

    @Autowired
    private UserWorksCommentManager userWorksCommentManager;

    /**
     * 评论审核申请
     * 
     * @param comment
     */
    public void applyComment(UserWorksComment comment) {
        ApplyEntity commentEntity = new ApplyEntity(this.commentEntity, String.valueOf(comment.getCommentId()));
        // 评论内容
        commentEntity.addContent(new ApplyText(commentContentField, comment.getContent()));
        // 评论图片
        if (Check.notNull(comment.getImage())) {
            commentEntity.addContent(new ApplyStorage(commentImageField, comment.getImage()));
        }

        // 申请
        AuditApply apply = new AuditApply(commentRegister, String.valueOf(
            comment.getCommentId()), comment.getCommentUserId(), commentEntity);
        AuditResult result = service.apply(apply);

        // 设置审核Id
        comment.setAuditRecordId(result.getRecordId());
        if (result.getStatus() == AuditStatus.REJECT) {
            // 审核拒绝
            BizAssert.throwBizException(ModuleConstant.AUDIT_FAILURE, "审核失败; 原因: {}", result.getReason());
        } else {
            // 其他状态
            resetAuditStatus(comment, result);
        }
    }

    /**
     * 评论审核结果通知
     * 
     * @param recordId
     */
    public void commentAuditNotify(AuditResult result) {
        UserWorksComment comment = userWorksCommentManager.getById(Integer.valueOf(result.getRootDataId()));
        if (Check.notNull(comment)) {
            resetAuditStatus(comment, result);
        } else {
            log.debug("评论={}不存在", result.getRootDataId());
        }
    }

    private void resetAuditStatus(UserWorksComment comment, AuditResult result) {
        // 内容是否修改
        if (result.getContentUpdate()) {
            EntityResult entityResult = result.getEntityResultList().get(0);
            for (FieldResult fieldResult : entityResult.getFieldResultList()) {
                if (fieldResult.getField().getName().equals(commentContentField.getName())) {
                    if (fieldResult.getContentUpdate()) {
                        comment.setContent(fieldResult.getNewContent());
                    }
                } else if (fieldResult.getField().getName().equals(commentImageField.getName())) {
                    if (fieldResult.getContentUpdate()) {
                        comment.setImage(fieldResult.getNewContent());
                    }
                }
            }
        }

        // 修改审核状态
        if (result.getStatus() == AuditStatus.PASS) {
            userWorksCommentManager.resetAuditStatus(comment,
                UserWorksCommentAuditStatus.PASS,
                result.getContentUpdate(),
                this.getClass().getSimpleName());
        } else if (result.getStatus() == AuditStatus.REJECT) {
            userWorksCommentManager.resetAuditStatus(comment,
                UserWorksCommentAuditStatus.REFUSE,
                result.getContentUpdate(),
                this.getClass().getSimpleName());
        } else {
            userWorksCommentManager.resetAuditStatus(comment,
                UserWorksCommentAuditStatus.WAITAUDIT,
                result.getContentUpdate(),
                this.getClass().getSimpleName());
        }
    }

}
